唉呀,今天再一篇v-for,不知道v-for分兩篇會不會覺得太灌水,但我還是分兩篇了✧*。٩(ˊᗜˋ*)و✧*。
當Vue正在更新使用v-for
渲染的元素列表時,它會默認使用就地更新
的策略。v-for
上所渲染的資料若是更動順序,DOM元素在渲染時,並不會隨便順序更動,而是就地更新每個元素,並確保他們在每個索引位置正確渲染,這樣的渲染方式若用於元素單純的狀態下其實是高效的。
這時候加上 key
屬性就可以解決這個問題!它可以讓 vue 有個依據來辨識每個節點。
拿前一天的兩個範例來說明!
我們在v-for
後面用v-bind
去綁定一個key
屬性,key
記得要綁定唯一的值!
<ul>
<li v-for="(item,index) in array" :key="index">
{{index+1}}. {{cute}}{{ item.pet }}
</li>
</ul>
<ul>
<li v-for="(value,name,index) in object" :key="name">
{{index+1}}.{{name}}:{{value}}
</li>
</ul>
再度提醒
v-bind
的縮寫是:
歐( ~'ω')~
v-for
除了我們昨天講到的array及object的渲染方式,它還有一個特殊的渲染方式,可以用整數做渲染,它會把模板重複對應次數。
像是n in 10
,n
表示目前所在數字,而10
表示範圍定義。
<ul>
<li v-for="n in 10">{{n}}</li>
</ul>
當我們想要呈現過濾後或排序後的數據,卻不想變更或重置原始數據,這時候我們就可以用到之前講過的計算屬性computed
來返回過濾後的數據了ε٩(๑> ₃ <)۶з
<div id="app">
<ul>
<li v-for="n in evenNumbers">{{ n }}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
numbers: [1, 2, 3, 4, 5]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
}
});
</script>
結果就只會顯示是偶數的2、4。
使用計算屬性可以解決大部分的需求,但如果資料有用到巢狀 v-for
的話,就沒辦法用計算屬性了,這時候我們可以改用方法methods
來達成需求╰(°▽°)╯
<div id="app">
<ul v-for="set in sets">
<li v-for="n in even(set)">{{ n }}</li>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
sets: [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
},
methods: {
even: function (numbers) {
return numbers.filter(function (number) {
return number % 2 === 0
})
}
}
});
</script>
<template>
上使用 v-for跟v-if
相同,v-for
也可以使用 <template>
一次渲染多個元素:
在這邊,index
、name
用一個<li>
渲染,而value
用不同的<li>
渲染。
<div id="app">
<ul>
<template v-for="(value,name,index) in object">
<li>{{index+1}}.{{name}}</li>
<li>{{value}}</li>
</template>
</ul>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
object: {
title: '菜鳥學前端,一起Vue起來!',
theme: 'Modern Web',
start: '2021.09.13'
}
},
});
</script>
當他們在同一個節點的時候,v-for
的優先級比 v-if
更高,所以v-if
將分別重複執行在每個v-for
的循環中。
<ul>
<li v-for="(value,name,index) in object" v-if="index > 0">
{{index+1}}.{{name}}:{{value}}
</li>
</ul>
data: {
object: {
title: '菜鳥學前端,一起Vue起來!',
theme: 'Modern Web',
start: '2021.09.13'
}
}
像這個例子,v-if
每次渲染前會經過v-for
,所以在這個例子它會執行三次,看起來就像:
<li v-if="index > 0"> {{index+1}}.{{name}}:{{value}}</li>
<li v-if="index > 0"> {{index+1}}.{{name}}:{{value}}</li>
<li v-if="index > 0"> {{index+1}}.{{name}}:{{value}}</li>
但判斷完後最後的結果只有兩個
<li>2.theme:Modern Web</li>
<li>3.start:2021.09.13</li>
所以如果我們的目的是想要有條件地跳過循環運行,我們可以把v-if
放在外層元素或是<template>
上。
歐耶,v-for是真的講完了喇,明天又是個新開始!!大家要加油啊啊啊,遠距了好久終於要回學校了,終於可以看到認識的人類們ㄌヾ(´∀ ˋ)ノ
但要比較早起床有點累哈哈哈